package com.atguigu.gmall.wms.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.exception.OrderException;
import com.atguigu.gmall.wms.entity.SkuLockVO;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.gmall.common.bean.PageResultVo;
import com.atguigu.gmall.common.bean.PageParamVo;

import com.atguigu.gmall.wms.mapper.WareSkuMapper;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import com.atguigu.gmall.wms.service.WareSkuService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuMapper, WareSkuEntity> implements WareSkuService {

    @Autowired
    WareSkuMapper wareSkuMapper;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    RabbitTemplate rabbitTemplate;
    private final static String LOCK_PREFIX = "stock:lock:";
    private final static String KEY_PREFIX = "stock:info:";
    @Autowired
    StringRedisTemplate redisTemplate;

    @Override
    public PageResultVo queryPage(PageParamVo paramVo) {
        IPage<WareSkuEntity> page = this.page(
                paramVo.getPage(),
                new QueryWrapper<WareSkuEntity>()
        );

        return new PageResultVo(page);
    }

    //对传输的skulockvo进行验库存及锁库存
    @Transactional
    @Override
    public List<SkuLockVO> checkAndLock(List<SkuLockVO> skuLockVO, String orderToken) {
        if (CollectionUtils.isEmpty(skuLockVO)){
           throw new OrderException("你没有要购买的商品");
        }
        skuLockVO.forEach(sku->{
           this.checkAndLock(sku);
        });
        //过滤没有锁成功的，将其解锁
        if (skuLockVO.stream().anyMatch(skulock->!skulock.getLock())){
            List<SkuLockVO> skulocks = skuLockVO.stream().filter(SkuLockVO::getLock).collect(Collectors.toList());
            skulocks.forEach(skulock1->{
            this.wareSkuMapper.unlock(skulock1.getWareId(),skulock1.getCount());
            });
            return skulocks;
        }
        //为了将来解锁库存，减库存，将库存锁住的库存信息存入redis中
        this.redisTemplate.opsForValue().set(KEY_PREFIX+orderToken, JSON.toJSONString(skuLockVO));
        this.rabbitTemplate.convertAndSend("ORDER_CREATE_EXCHANGE","stock.ttl",orderToken);
        return null;
    }

    public void checkAndLock(SkuLockVO skuLockVO){
        RLock fairLock = redissonClient.getFairLock(LOCK_PREFIX + skuLockVO.getSkuId());
        fairLock.lock();
        try {
            List<WareSkuEntity> wareSkuEntities = this.wareSkuMapper.checkWare(skuLockVO.getSkuId(), skuLockVO.getCount());
            if (CollectionUtils.isEmpty(wareSkuEntities)){
                //说明没有库存了
                skuLockVO.setLock(false);
            }else {//说明有库存
            WareSkuEntity wareSkuEntity = wareSkuEntities.get(0);
           if(this.wareSkuMapper.lockWare(wareSkuEntity.getId(),skuLockVO.getCount())==1){
            skuLockVO.setLock(true);
            skuLockVO.setWareId(wareSkuEntity.getId());
           }else {
               skuLockVO.setLock(false);
           }
            }
        } finally {
    fairLock.unlock();
        }


    }

}